
import {Websock} from './websock'
import {chatEvents} from '../chatEvents'
import EventEmitter from '../../common/EventEmitter'
export default class XchatWebsocket{
	constructor(wb_param = null,xchat_protocol = {}) {
	  this.wb_param = wb_param
		console.log("xchat_protocol:"+xchat_protocol.member_in_out_hint)
		this.xchat_protocol = xchat_protocol
		this.init()
	}
	init(){
		this.ws = null
		this.error_count = 0
		this.heartbeat_ref = null
		this.emitter = new EventEmitter()
		this.passport = '0'
		this.lockReconnect = false //避免一直重连
		this.reconnectTimer = null
		console.log(">> connect")
		if(this.ws){
			this.ws.close()
		}
		this.connectWb()
	}
	reconnect(){
		if(this.lockReconnect){
			return
		}
		this.lockReconnect = true
		if(this.reconnectTimer){
			clearTimeout(this.reconnectTimer)
		}
		this.reconnectTimer = setTimeout(()=>{
			this.lockReconnect = false
			this.emitter.trigger(chatEvents.MSG_SOCKET_RECONNECT)
			this.connectWb()
		},3000)
	}
	connectWb() {
		var schema = "ws://"
		var websockPath = "/websockify"
		var uri
		if (this.wb_param.wss) {
			schema = "wss://"
			uri = schema + this.wb_param.wss + websockPath
		} else {
			uri =  schema + this.wb_param.ip + ":" + this.wb_param.port + websockPath
		}
		try{
			this.ws = new Websock()
			this.ws.open(uri)
		}catch(e){
			this.reconnect()
		}
		if(this.heartbeat_ref === null){
			this.heartbeat_ref = setInterval(this.heartbeat.bind(this), 1000*15)
		}
		this.ws.on('message', ()=>{this.do_recv()})
		this.ws.on('open', this.do_open.bind(this))
		this.ws.on('close', this.do_error.bind(this))
	}
	do_open(e) {
		console.log(">> WebSockets.onopen");
		//send login packet
		let login_timer = setInterval(()=>{
			if(this.ws.get_state() == 1){
				if("packet_login" in this.xchat_protocol){
					this.ws.send(this.xchat_protocol.packet_login(this.wb_param.room_id,this.wb_param.uid,this.wb_param.level,this.wb_param.appdata,this.wb_param.token))
				}
				clearInterval(login_timer)
			}
		},1000);
	}
	do_error(e){
		this.xchat_protocol.logined = false
		if (this.error_count>=5){
			this.emitter.trigger(chatEvents.MSG_SOCKET_ERROR)
			return
		}
		if (!this.xchat_protocol.Closed_By_Server && !this.xchat_protocol.Closed_By_Client){
			this.error_count += 1
			this.reconnect()
		}else{
			this.emitter.trigger(chatEvents.MSG_SOCKET_ERROR)
		}
	}
	heartbeat() {
		if (this.ws && this.ws.get_state() == 1 && this.xchat_protocol.logined){
			this.ws.send(this.xchat_protocol.packet_heartbeat())
		}
	}
	logout(){
		if (this.ws) {
			this.ws.on('close', function(){})
			this.ws.send(this.xchat_protocol.packet_logout())
			this.ws.close()
		}
	}
	do_recv(){
		//连接建立成功
		this.error_count = 0
		while(1){
			if (this.xchat_protocol.packet_fetch_state == 0){
				if(this.ws.rQlen() >= 4){
					this.xchat_protocol.packet_header = this.ws.rQshiftBytes(4);
					this.xchat_protocol.parse_header();
					this.xchat_protocol.packet_fetch_state = 1
				}
				else{
					break;
				}
			}
			else{
				if (this.ws.rQlen() >= this.xchat_protocol.packet_body_length){
					this.xchat_protocol.packet_body = this.ws.rQshiftBytes(this.xchat_protocol.packet_body_length)
					this.xchat_protocol.packet_fetch_state = 0
					this.xchat_protocol.process_packet(this.emitter,chatEvents)
				}
				else{
					break;
				}
			}
		}
	}
	on(event, listener) {
		this.emitter.on(event, listener)
	}
	off(event, listener) {
		this.emitter.off(event, listener)
	}
}